using System;

namespace SBPweb.Modules.Dependencies
{

	/// <summary>
	/// This class implements IVersionDependency interface, implements basic funcionallity 
	/// for version dependency handling
	/// </summary>
	/// <typeparam name="T"></typeparam>
    public abstract class VersionDependency<T> : IVersionDependency
    {

        #region Private fields

        private T pT;
        private string pValue;
        private VersionMask pVersionMask;
        private System.Version pMinVersion;
        private System.Version pMaxVersion;
        private bool pIsMet = false;

        #endregion

        #region Protected fields

		/// <summary>
		/// Depender version
		/// </summary>
        protected System.Version pVersion;

        #endregion

        #region Constructor logic

        /// <summary>
		/// Initializes a new VersionDependency instance
		/// </summary>
		/// <param name="value">Version criteria - can be a version mask or range</param>
		/// <param name="t">instance of type T</param>
		public VersionDependency(string value, T t)
        {
            pT = t;
            pValue = value;
            SetValueProperties();
            pIsMet = CheckIfMet();
        }

        #endregion

        #region Property accessors

        /// <summary>
        /// Version mask
        /// </summary>
		public VersionMask Mask
        {
            get
            {
                return pVersionMask;
            }
        }

		/// <summary>
		/// Minimum version
		/// </summary>
		public System.Version MinimumVersion
        {
            get
            {
                return pMinVersion;
            }
        }

		/// <summary>
		/// Maximum version
		/// </summary>
		public System.Version MaximumVersion
        {
            get
            {
                return pMaxVersion;
            }
        }

		/// <summary>
		/// Returns true if version is met with the given Mask, MinimumVersion and MaximumVersion
		/// </summary>
		public bool IsMet
        {
            get
            {
                return pIsMet;
            }
        }

	    /// <summary>
	    /// Returns the depender
	    /// </summary>
		public T Depender
        {
            get
            {
                return pT;
            }
        }

        #endregion

        #region Abstract / virtual methods
		
		/// <summary>
		/// Checks if the depender's version met with the given mask, minumum and maximum version
		/// </summary>
		/// <returns></returns>
        protected virtual bool CheckIfMet()
        {
            if (Depender == null)
            {
                return false;
            }
            if (pVersion == null)
            {
                ExtractVersion();
            }
            if (Mask != null)
            {
                return Mask.IsMet(pVersion);
            }
            if (MinimumVersion != null && pVersion.CompareTo(MinimumVersion) <= 0)
            {
                return false;
            }
            if (MaximumVersion != null && pVersion.CompareTo(MaximumVersion) >= 0)
            {
                return false;
            }

            return false;
        }

        /// <summary>
        /// This method extracts version of the depender
        /// </summary>
		protected abstract void ExtractVersion();

        #endregion

        #region Protected helper functions

		/// <summary>
		/// This method parses the Value string to minimum and maximum version or version mask
		/// </summary>
        protected void SetValueProperties()
        {
            string[] split = pValue.Split(new char[] { '-' }, StringSplitOptions.None);
            if (split.Length < 2)
            {
                pVersionMask = new VersionMask(split[0]);
            }
            else
            {
                if (!string.IsNullOrEmpty(split[0]))
                {
                    pMinVersion = new System.Version(split[0]);
                }
                if (!string.IsNullOrEmpty(split[1]))
                {
                    pMaxVersion = new System.Version(split[1]);
                }
            }
        }

        #endregion

        #region Overridden methods

		/// <summary>
		/// This method returns the string representation of the object
		/// </summary>
		/// <returns></returns>
        public override string ToString()
        {
            return string.Format("Depender: {0}, IsMet: {1}, Mask: [{2}], Min: [{3}], Max: [{4}]",
                (Depender != null) ? (Depender.ToString()) : ("null"),
                (IsMet), 
                (Mask != null) ? (Mask.ToString()) : ("null"),
                (MinimumVersion != null) ? (MinimumVersion.ToString()) : ("null"),
                (MaximumVersion != null) ? (MaximumVersion.ToString()) : ("null")
                );
        }

        #endregion

    }
}
